﻿using System;
using Platformer_Example.Controller.Data;
using Transformable_Engine_v2.Engine.Helper;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Platformer_Example.Controller.Character.Attack
{
    public class AttackDescription
    {
        public AttackDescription(AttackType type, AttackTargets target, TE_Rectangle hitbox, TE_Vector2 pushback, int disableTime)
        {
            DisableTime = disableTime;
            Pushback = pushback;
            Hitbox = hitbox;
            Target = target;
            Type = type;
        }

        public enum AttackType
        {
            Normal,
            Unblockable,
            Projectile
        }
        public AttackType Type { get; private set; }

        public enum AttackTargets
        {
            Any,
            NotInTeam,
            InTeam,
        }
        public AttackTargets Target { get; private set; }

        public TE_Rectangle Hitbox { get; private set; }

        public TE_Vector2 Pushback { get; private set; }

        public int DisableTime { get; private set; }

        public bool IsInAttackArea(IAttackable attackable, IAttacker attacker)
        {
            var hitbox = GetHitboxRectangle(attacker.GetDirection()) + attacker.GetAbsolutePosition();
            var attackableHitbox = attackable.GetHitBoundingBox() + attackable.GetAbsolutePosition();

            return CollisionHelper.Intersects(hitbox, attackableHitbox);
        }

        public TE_Rectangle GetHitboxRectangle(BaseInputCharacter.Direction direction)
        {
            return direction == BaseInputCharacter.Direction.Right ? Hitbox : Hitbox.FlipHorizontally;
        }

        public bool IsValidTarget(IAttackable attackable, IAttacker attacker)
        {
            if (!attackable.IsAttackable())
                return false;

            if (Type == AttackType.Projectile && attackable.IsReflecting())
            {
                attacker.Reflect();
                return false;
            }

            if (Type != AttackType.Unblockable && attackable.IsDefending())
                return false;
            
            
            switch (Target)
            {
                case AttackTargets.Any:
                    return true;
                case AttackTargets.NotInTeam:
                    return attackable.GetTeam() != attacker.GetTeam();
                case AttackTargets.InTeam:
                    return attackable.GetTeam() == attacker.GetTeam();
            }

            return false;
        }
    }
}